package com.cssy.xxkj.logic.service.impl;


import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicPayDAO;
import com.cssy.xxkj.logic.dao.LogicPayItemDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseWareDAO;
import com.cssy.xxkj.logic.dao.LogicPurchaseWareItemDAO;
import com.cssy.xxkj.logic.entity.LogicPayDO;
import com.cssy.xxkj.logic.entity.LogicPayItemDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseWareDO;
import com.cssy.xxkj.logic.entity.LogicPurchaseWareItemDO;
import com.cssy.xxkj.logic.service.ILogicPayService;
import com.cssy.xxkj.logic.service.ILogicUtilService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;

@Service("logicPayService")
public class LogicPayServiceImpl implements ILogicPayService{
	
    @Resource(name="logicPayDAO")
	private LogicPayDAO logicPayDAO;
    
    @Resource(name="logicPayItemDAO")
    private LogicPayItemDAO logicPayItemDAO;
    
    @Resource(name="logicPurchaseWareDAO")
    private LogicPurchaseWareDAO logicPurchaseWareDAO;
    
    @Resource(name="logicPurchaseWareItemDAO")
    private LogicPurchaseWareItemDAO logicPurchaseWareItemDAO;
    
    @Resource(name="logicUtilService")
    private ILogicUtilService logicUtilService; 
    
    @Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs=new SearchResult(scs);
		List<LogicPayDO> list=logicPayDAO.find(scs);
		rs.setRecordCount(logicPayDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		Integer i=logicPayDAO.deleteLogicPayDOByPrimaryKey(id);
		return i;
	}

	@Override
	public Integer update(LogicPayDO curAP, User user) throws SyBaseException {
		curAP.setBizModifyDate(new Date());
		curAP.setBizModifyName(user.getName());
		curAP.setBizVersionMark(curAP.getBizVersion()+1);
		return logicPayDAO.updateLogicPayDO(curAP);
	}

	@Override
	public LogicPayDO save(LogicPayDO curAP, User user) throws SyBaseException {
		if(curAP.getBizCreatorDate()==null){
			curAP.setBizCreatorDate(new Date());
		}
		curAP.setBizCreatorName(user.getName());
		curAP.setBizVersion(Integer.valueOf(1));
        logicPayDAO.insertLogicPayDO(curAP);
		return curAP;
	}

	@Override
	public LogicPayDO findListById(String id) throws SyBaseException {
		return logicPayDAO.findLogicPayDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		return logicPayDAO.deleteBizRemoved(id);
	}

	@Override
	public List<LogicPayItemDO> findItemListByMap(Map<String, Object> paramMap)
			throws SyBaseException {
		return logicPayItemDAO.findItemListByMap(paramMap);
	}
	
	@Override
	public Map<String, BigDecimal> findHasPayItemListByMap(Map<String, Object> paramMap)
			throws SyBaseException {
		List<LogicPayItemDO> payItemList = logicPayItemDAO.findItemListByMap(paramMap);
		if(payItemList==null||payItemList.isEmpty()||payItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> payHasMap = new HashMap<String, BigDecimal>();
			for(LogicPayItemDO payItem : payItemList){
				if(payItem==null||StringUtils.isBlank(payItem.getId())){
					continue;
				}
				String keyStr = payItem.getZd002MaterId()+"_"+payItem.getZd007Model()+"_"
						+payItem.getZd011Size()+"_"+payItem.getZd009Color()+"_"
						+payItem.getZd010Quality();
				BigDecimal pzdThMoney = payItem.getZd018TheMoney()==null?BigDecimal.ZERO:payItem.getZd018TheMoney();
				if(payHasMap.get(keyStr)==null){
					payHasMap.put(keyStr, pzdThMoney);
				}else{
					payHasMap.put(keyStr, pzdThMoney.add(payHasMap.get(keyStr)));
				}
			}
			return payHasMap;
		}
	}
	
	@Override
	public BigDecimal findQueryHasPayMoney(Map<String, Object> paramMap)throws SyBaseException{
		List<LogicPayItemDO> payItemList = logicPayItemDAO.findItemListByMap(paramMap);
		if(payItemList==null||payItemList.isEmpty()||payItemList.size()==0){
			return BigDecimal.ZERO;
		}else{
			BigDecimal hasSumMoney = BigDecimal.ZERO;
			for(LogicPayItemDO payItem : payItemList){
				if(payItem==null){
					continue;
				}
				BigDecimal theMoney = payItem.getZd018TheMoney()==null?BigDecimal.ZERO:payItem.getZd018TheMoney();
				hasSumMoney = hasSumMoney.add(theMoney);
			}
			
			return hasSumMoney;
		}
	}

	/**
	 * 付款保存
	 */
	@Override
	public void paySave(LogicPayDO curAP, HttpServletRequest request)
			throws SyBaseException{
		String payDate = request.getParameter("zd014PayDate");
		if(StringUtils.isNotBlank(payDate)){
			curAP.setZd014PayDate(DateUtils.stringToDate(payDate));
		}else{
			curAP.setZd014PayDate(new Date());
		}
		String itemdata = request.getParameter("itemdata");
		String itemdelete = request.getParameter("itemdelete");//删除
		try {
			//默认是未付款状态
			curAP.setZd003PayStatus(BillStatusUtil.PAY_MONEY_BILL_STATUS_ONE);
			String payId = "";
			String payCode = "";
 			if(curAP==null || StringUtils.isBlank(curAP.getId())){
 				//新增
 				payId = IDCodeTypeUtil.getId();
 				payCode = syCodeService.getCode(BillTypeConstant.PAY,
						BillTypeConstant.PAY, SyCode.DATE_YYMM, 5);
 				curAP.setId(payId);
 				curAP.setZd001PayCode(payCode);
 				this.save(curAP, SessionUtil.getUser(request));
 			}else{
 				//修改
 				Integer row = this.update(curAP, SessionUtil.getUser(request));
 				if(row==null||row.intValue()==0){
 					throw new SyBaseException("数据发生错误，请重新提交。");
 				}else{
 					if(StringUtils.isNotBlank(itemdelete)){
 						List<LogicPayItemDO> pmList = JSONArray.parseArray(itemdelete, LogicPayItemDO.class);
 						for(LogicPayItemDO payItem : pmList){
 							if(payItem==null || StringUtils.isBlank(payItem.getId())){
 								continue;
 							}
 							logicPayItemDAO.deleteLogicPayItemDOByPrimaryKey(payItem.getId());
 						}
 					}
 				}
 			}
 			//收款行记录表
 			List<LogicPayItemDO> payItemList = JSONArray.parseArray(itemdata, LogicPayItemDO.class);
 			for(LogicPayItemDO payItem : payItemList){
 				if(payItem==null){
 					continue;
 				}
 				if(StringUtils.isBlank(payItem.getId())){
 					//新增
 					payItem.setId(IDCodeTypeUtil.getId());
 					payItem.setZd001PayId(payId);
 					payItem.setZd001PayCode(payCode);
 					logicPayItemDAO.insertLogicPayItemDO(payItem);
 				}else{
 					logicPayItemDAO.updateLogicPayItemDO(payItem);
 				}
 			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}

	@Override
	public void payCommit(LogicPayDO curAP, HttpServletRequest request)
			throws SyBaseException{
		try {
			String payDate = request.getParameter("zd014PayDate");
			if(StringUtils.isNotBlank(payDate)){
				curAP.setZd014PayDate(DateUtils.stringToDate(payDate));
			}else{
				curAP.setZd014PayDate(new Date());
			}
			String itemdata = request.getParameter("itemdata");
			String itemdelete = request.getParameter("itemdelete");//删除
			//不提交的付款
			if(StringUtils.isNotBlank(itemdelete)){
				List<LogicPayItemDO> pmList = JSONArray.parseArray(itemdelete, LogicPayItemDO.class);
				for(LogicPayItemDO payItem : pmList){
					if(payItem==null || StringUtils.isBlank(payItem.getId())){
						continue;
					}
					logicPayItemDAO.deleteLogicPayItemDOByPrimaryKey(payItem.getId());
				}
			}
			//提交的付款
			List<LogicPayItemDO> payItemList = JSONArray.parseArray(itemdata, LogicPayItemDO.class);
			Map<String, BigDecimal> payHasMap = this.findHasPayQueryToMap(curAP.getZd002PcswId());
			Map<String, LogicPurchaseWareItemDO> pcsmItemMap = this.findQueryPcsmToMap(curAP.getZd002PcswId());
			for(LogicPayItemDO payItem : payItemList){
				if(payItem == null){
					continue;
				}
				String keyStr = curAP.getZd002PcswId()+"_"+payItem.getZd002MaterId()+"_"
						+payItem.getZd007Model()+"_"+payItem.getZd011Size()+"_"
						+payItem.getZd009Color()+"_"+payItem.getZd010Quality();
				//应付总金额
				BigDecimal zdSmMoney = payItem.getZd016Amount()==null?BigDecimal.ZERO:payItem.getZd016Amount();
				//本次付款金额
				BigDecimal zdThMoney = payItem.getZd018TheMoney()==null?BigDecimal.ZERO:payItem.getZd018TheMoney();
				//当前付款总金额
				BigDecimal zdThSmMoney = BigDecimal.ZERO;
				if(payHasMap==null||payHasMap.get(keyStr)==null){
					zdThSmMoney = zdThMoney;
				}else{
					BigDecimal zdExMoney = payHasMap.get(keyStr);
					zdThSmMoney = zdThMoney.add(zdExMoney);
				}
				//comMoney = 应付总金额-当前总金额
				BigDecimal comMoney = zdSmMoney.subtract(zdThSmMoney);
				int compSt = BigDecimal.ZERO.compareTo(comMoney);
				if(compSt==1){
					throw new SyBaseException("本次付款的金额大于应付金额，请检查。");
				}else{
					if(payHasMap==null){
						payHasMap = new HashMap<String, BigDecimal>();
					}
					payHasMap.put(keyStr, zdThSmMoney);
				}
			}
			LogicPurchaseWareDO pcsw = this.findPurchaseWare(curAP.getZd002PcswId());
			boolean canUpSt = true;
			if(pcsmItemMap==null){
				throw new SyBaseException("没有查询到采购入库单的物料集合。");
			}else{
				for(LogicPurchaseWareItemDO pcswmItem : pcsmItemMap.values()){
					if(pcswmItem==null){
						continue;
					}
					String keyStr = curAP.getZd002PcswId()+"_"+pcswmItem.getZd003MaterId()+"_"
							+pcswmItem.getZd007Model()+"_"+pcswmItem.getZd011Size()+"_"
							+pcswmItem.getZd009Color()+"_"+pcswmItem.getZd010Quality();
					//已付款数
					BigDecimal tempMoney = BigDecimal.ZERO;
					if(payHasMap.get(keyStr)==null){
						tempMoney = BigDecimal.ZERO;
					}else{
						tempMoney = payHasMap.get(keyStr);
						BigDecimal zdQuantity = pcswmItem.getZd018HsQuantity()==null?BigDecimal.ZERO:pcswmItem.getZd018HsQuantity();
						BigDecimal zdPrice = pcswmItem.getZd016Price()==null?BigDecimal.ZERO:pcswmItem.getZd016Price();
						//应付款数
						BigDecimal zdHasMoney = zdQuantity.multiply(zdPrice);
						//本次
						//减去数量
						BigDecimal upMoney = zdHasMoney.subtract(tempMoney);
						int upComp = BigDecimal.ZERO.compareTo(upMoney);
						if(upComp==1){
							throw new SyBaseException("付款总额大于应付款。");
						}
						if(upComp==-1){
							canUpSt = false;
						}
					}
				}
			}
			
			if(canUpSt){
				//完全付款
				pcsw.setZd004PayStatus(BillStatusUtil.PCSW_PAY_BILL_STATUS_THREE);
				curAP.setZd003PayStatus(BillStatusUtil.PCSW_PAY_BILL_STATUS_THREE);
			}else{
				//部分付款
				pcsw.setZd004PayStatus(BillStatusUtil.PCSW_PAY_BILL_STATUS_TWO);
				curAP.setZd003PayStatus(BillStatusUtil.PCSW_PAY_BILL_STATUS_TWO);
			}
			logicPurchaseWareDAO.updateLogicPurchaseWareDO(pcsw);
			this.update(curAP, SessionUtil.getUser(request));
		} catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed()+ e.getMessage());
		}
	}
	
	
	private Map<String, BigDecimal> findHasPayQueryToMap(String pcswId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pcswId", pcswId);
		paramMap.put("zdStatus", BillStatusUtil.PAY_BILL_STATUS_TWO);
		List<LogicPayItemDO> payItemList =  logicPayItemDAO.findItemListByMap(paramMap);
		if(payItemList==null||payItemList.isEmpty()||payItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> payHasMap = new HashMap<String, BigDecimal>();
			for(LogicPayItemDO payItem : payItemList){
				if(payItem==null){
					continue;
				}
				String keyStr = pcswId+"_"+payItem.getZd002MaterId()+"_"
						+payItem.getZd007Model()+"_"+payItem.getZd011Size()+"_"
						+payItem.getZd009Color()+"_"+payItem.getZd010Quality();
				BigDecimal theMoney = payItem.getZd018TheMoney()==null?BigDecimal.ONE:payItem.getZd018TheMoney();
				if(payHasMap.get(keyStr)==null){
					payHasMap.put(keyStr, theMoney);
				}else{
					payHasMap.put(keyStr, theMoney.add(payHasMap.get(keyStr)));
				}
			}
			return payHasMap;
		}
	}
	
	private Map<String, LogicPurchaseWareItemDO> findQueryPcsmToMap(String pcswId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("pcswId", pcswId);
		List<LogicPurchaseWareItemDO> pcswmList = logicPurchaseWareItemDAO.findListByMap(paramMap);
		if(pcswmList==null||pcswmList.isEmpty()||pcswmList.size()==0){
			return null;
		}else{
			Map<String, LogicPurchaseWareItemDO> pcswmMap = new HashMap<String, LogicPurchaseWareItemDO>();
			for(LogicPurchaseWareItemDO pcswm : pcswmList){
				if(pcswm==null){
					continue;
				}
				String keyStr = pcswId+"_"+pcswm.getZd003MaterId()+"_"+pcswm.getZd007Model()+"_"
						+pcswm.getZd011Size()+"_"+pcswm.getZd009Color()+"_"
						+pcswm.getZd010Quality();
				pcswmMap.put(keyStr, pcswm);
			}
			return pcswmMap;
		}
	}
	
	/**
	 * 
	 * @param pcswId
	 * @return
	 */
	private LogicPurchaseWareDO findPurchaseWare(String pcswId){
		LogicPurchaseWareDO pcsw = null;
		SearchConditions pcswScs = new SearchConditions();
		pcswScs.setRemovedProperty(null);
		pcswScs.addCondition("id", pcswId, SearchCondition.OP_EQUAL);
		List<LogicPurchaseWareDO> pcswList = logicUtilService.resultPurchaseWare(pcswScs);
		if(pcswList==null||pcswList.isEmpty()||pcswList.size()==0){
			throw new SyBaseException("");
		}else{
			pcsw = pcswList.get(0);
		}
		return pcsw;
	}
}
